#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef __BMP_H__
#define __BMP_H__

typedef struct 
{
  // File header.
  unsigned short int type;
  long  size;
  unsigned short int reserve1;
  unsigned short int reserve2;
  long offBits;                     

  // BMP Header.
  long bmpSize;
  long bmpWidth;
  long bmpHeight;
  unsigned short int bmpPlanes;
  unsigned short int bmpBitCount;  
  long bmpCompression;
  long bmpSizeImage;
  long bmpXPelsPerMeter;
  long bmpYPelsPerMeter;
  long bmpClrUsed;
  long bmpClrImportant;
  
} tBMPHeader;                       // Encabezado del archivo BMP.

typedef tBMPHeader* tpBMPHeader;

typedef struct {
    unsigned char R;
    unsigned char G;
    unsigned char B;
} tPixel24;                         // Tipo de dato Pixel de 24 bits.

#define OPT_TRANSFORM_LENGTH 10     // Maxima cantidad de secciones del archivo.
#define OPT_TRANSFORM_END -1        // Indica fin de parametros de transformacion

typedef int tOptTransform [OPT_TRANSFORM_LENGTH];

typedef char* tDescriptor;

/*
 *  initOptions:
 *      Inicializa los parametros de transformacion a partir de un descriptor.
 *  params:
 *      pOpt: Descriptor de la transformacion (Ej.: "0:2:1")
 *  pre:
 *      ninguna.
 *  pos: 
 *      retorna un dato tDescriptor que describe la transofrmacion a llevar a cabo.
 * 
 */
void initOptions (tOptTransform* pOptTrans, tDescriptor pOpt);

/*
 * cntColumnasTransformacion:
 *      Contabiliza la cantidad de columnas en las que se divide la imagen para llevar
 * a cabo la transformacion.
 * 
 * Params:
 *  pOptTrans: Parametros de transformacion.
 * 
 * Pre: Los parametros de transformacion debe haber sido inicializados mediante initOptions.
 * Post: Retorna el numero de columnas con el cual dividir la imagen.
 * 
 */
int cntColumnasTransformacion (tOptTransform pOptTrans);

/*
 * readBMPHeader:
 *      Lee de stream el header del archivo BMP.
 *  Pre: El stream debe estar abierto y apuntando al inicio del archivo.  ppHeader debe 
 *  referenciar a un elemento de tipo tBMPHeader.
 *  Pos: vuelca en el elemento de tipo tBMPHeader referenciado por ppHeader la 
 *  informacion del encabezado del archivo BMP.    
 * 
 */
int readBMPHeader(tpBMPHeader ppHeader, FILE* stream);

/*
 * printBMPHeader:
 *      Imprime en outStream el encabezado pHeader.
 * pre: outStream debe estar inicializado y listo para escribir.  pHeader debe
 * estar inicializado.
 * pos: Imprime en outStream el contenido de pHeader.
 * 
 */
int printBMPHeader (FILE* outStream, tBMPHeader pHeader);

/*
 * transformarBMP:
 *    aplica la transofrmacion descripta por optTrans al archivo bmp representado
 * por inStream y guarda el resultado en el archivo representado por outStream.
 * Pre:  optTrans debe estar inicializado mediante initOptions. inStream
 * debe estar inicializado, listo para leer en forma binaria y apuntando al inicio 
 * del archivo.  outStream debe estar inicializado y listo para poder escribir en 
 * forma binaria.
 * 
 */
int transformarBMP (FILE* outStream, FILE* inStream,tOptTransform optTrans);

#endif
